{
 "cells": [
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# 推論のための多言語モデル"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "🤗 Transformers にはいくつかの多言語モデルがあり、それらの推論の使用方法は単一言語モデルとは異なります。ただし、多言語モデルの使用方法がすべて異なるわけではありません。 [google-bert/bert-base-multilingual-uncased](https://huggingface.co/google-bert/bert-base-multilingual-uncased) などの一部のモデルは、単一言語モデルと同様に使用できます。 このガイドでは、推論のために使用方法が異なる多言語モデルをどのように使うかを示します。"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## XLM"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "XLM には10の異なるチェックポイントがあり、そのうちの1つだけが単一言語です。 残りの9つのモデルチェックポイントは、言語埋め込みを使用するチェックポイントと使用しないチェックポイントの2つのカテゴリに分けることができます。"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### 言語の埋め込みがある XLM"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "次の XLM モデルは、言語の埋め込みを使用して、推論で使用される言語を指定します。\n",
    "\n",
    "- `FacebookAI/xlm-mlm-ende-1024` (マスク化された言語モデリング、英語-ドイツ語)\n",
    "- `FacebookAI/xlm-mlm-enfr-1024` (マスク化された言語モデリング、英語-フランス語)\n",
    "- `FacebookAI/xlm-mlm-enro-1024` (マスク化された言語モデリング、英語-ルーマニア語)\n",
    "- `FacebookAI/xlm-mlm-xnli15-1024` (マスク化された言語モデリング、XNLI 言語)\n",
    "- `FacebookAI/xlm-mlm-tlm-xnli15-1024` (マスク化された言語モデリング + 翻訳 + XNLI 言語)\n",
    "- `FacebookAI/xlm-clm-enfr-1024` (因果言語モデリング、英語-フランス語)\n",
    "- `FacebookAI/xlm-clm-ende-1024` (因果言語モデリング、英語-ドイツ語)\n",
    "\n",
    "言語の埋め込みは、モデルに渡される `input_ids` と同じ形状のテンソルとして表されます。 これらのテンソルの値は、使用される言語に依存し、トークナイザーの `lang2id` および `id2lang` 属性によって識別されます。\n",
    "\n",
    "この例では、`FacebookAI/xlm-clm-enfr-1024` チェックポイントをロードします (因果言語モデリング、英語-フランス語)。"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "import torch\n",
    "from transformers import XLMTokenizer, XLMWithLMHeadModel\n",
    "\n",
    "tokenizer = XLMTokenizer.from_pretrained(\"FacebookAI/xlm-clm-enfr-1024\")\n",
    "model = XLMWithLMHeadModel.from_pretrained(\"FacebookAI/xlm-clm-enfr-1024\")"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "トークナイザーの `lang2id` 属性は、このモデルの言語とその ID を表示します。"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "{'en': 0, 'fr': 1}"
      ]
     },
     "execution_count": null,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "print(tokenizer.lang2id)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "次に、入力例を作成します。"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "input_ids = torch.tensor([tokenizer.encode(\"Wikipedia was used to\")])  # batch size of 1"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "言語 ID を `en` に設定し、それを使用して言語の埋め込みを定義します。 言語の埋め込みは、英語の言語 ID であるため、`0` で埋められたテンソルです。 このテンソルは `input_ids` と同じサイズにする必要があります。"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "language_id = tokenizer.lang2id[\"en\"]  # 0\n",
    "langs = torch.tensor([language_id] * input_ids.shape[1])  # torch.tensor([0, 0, 0, ..., 0])\n",
    "\n",
    "# We reshape it to be of size (batch_size, sequence_length)\n",
    "langs = langs.view(1, -1)  # is now of shape [1, sequence_length] (we have a batch size of 1)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "これで、`input_ids` と言語の埋め込みをモデルに渡すことができます。"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "outputs = model(input_ids, langs=langs)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "[run_generation.py](https://github.com/huggingface/transformers/tree/main/examples/pytorch/text-generation/run_generation.py) スクリプトは、`xlm-clm` チェックポイントを使用して、言語が埋め込まれたテキストを生成できます。"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### 言語の埋め込みがないXLM"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "次の XLM モデルは、推論中に言語の埋め込みを必要としません。\n",
    "\n",
    "- `FacebookAI/xlm-mlm-17-1280` (マスク化された言語モデリング、17の言語)\n",
    "- `FacebookAI/xlm-mlm-100-1280` (マスク化された言語モデリング、100の言語)\n",
    "\n",
    "これらのモデルは、以前の XLM チェックポイントとは異なり、一般的な文の表現に使用されます。"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## BERT"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "以下の BERT モデルは、多言語タスクに使用できます。\n",
    "\n",
    "- `google-bert/bert-base-multilingual-uncased` (マスク化された言語モデリング + 次の文の予測、102の言語)\n",
    "- `google-bert/bert-base-multilingual-cased` (マスク化された言語モデリング + 次の文の予測、104の言語)\n",
    "\n",
    "これらのモデルは、推論中に言語の埋め込みを必要としません。 文脈から言語を識別し、それに応じて推測する必要があります。"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## XLM-RoBERTa"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "次の XLM-RoBERTa モデルは、多言語タスクに使用できます。\n",
    "\n",
    "- `FacebookAI/xlm-roberta-base` (マスク化された言語モデリング、100の言語)\n",
    "- `FacebookAI/xlm-roberta-large` (マスク化された言語モデリング、100の言語)\n",
    "\n",
    "XLM-RoBERTa は、100の言語で新しく作成およびクリーニングされた2.5 TB の CommonCrawl データでトレーニングされました。 これは、分類、シーケンスのラベル付け、質問応答などのダウンストリームタスクで、mBERT や XLM などの以前にリリースされた多言語モデルを大幅に改善します。"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## M2M100"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "次の M2M100 モデルは、多言語翻訳に使用できます。\n",
    "\n",
    "- `facebook/m2m100_418M` (翻訳)\n",
    "- `facebook/m2m100_1.2B` (翻訳)\n",
    "\n",
    "この例では、`facebook/m2m100_418M` チェックポイントをロードして、中国語から英語に翻訳します。 トークナイザーでソース言語を設定できます。"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from transformers import M2M100ForConditionalGeneration, M2M100Tokenizer\n",
    "\n",
    "en_text = \"Do not meddle in the affairs of wizards, for they are subtle and quick to anger.\"\n",
    "chinese_text = \"不要插手巫師的事務, 因為他們是微妙的, 很快就會發怒.\"\n",
    "\n",
    "tokenizer = M2M100Tokenizer.from_pretrained(\"facebook/m2m100_418M\", src_lang=\"zh\")\n",
    "model = M2M100ForConditionalGeneration.from_pretrained(\"facebook/m2m100_418M\")"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "テキストをトークン化します。"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "encoded_zh = tokenizer(chinese_text, return_tensors=\"pt\")"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "M2M100 は、最初に生成されたトークンとしてターゲット言語 ID を強制的にターゲット言語に翻訳します。 英語に翻訳するには、`generate` メソッドで `forced_bos_token_id` を `en` に設定します。"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "'Do not interfere with the matters of the witches, because they are delicate and will soon be angry.'"
      ]
     },
     "execution_count": null,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "generated_tokens = model.generate(**encoded_zh, forced_bos_token_id=tokenizer.get_lang_id(\"en\"))\n",
    "tokenizer.batch_decode(generated_tokens, skip_special_tokens=True)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## MBart"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "多言語翻訳には、次の MBart モデルを使用できます。\n",
    "\n",
    "- `facebook/mbart-large-50-one-to-many-mmt` (One-to-many multilingual machine translation, 50 languages)\n",
    "- `facebook/mbart-large-50-many-to-many-mmt` (Many-to-many multilingual machine translation, 50 languages)\n",
    "- `facebook/mbart-large-50-many-to-one-mmt` (Many-to-one multilingual machine translation, 50 languages)\n",
    "- `facebook/mbart-large-50` (Multilingual translation, 50 languages)\n",
    "- `facebook/mbart-large-cc25`\n",
    "\n",
    "この例では、`facebook/mbart-large-50-many-to-many-mmt` チェックポイントをロードして、フィンランド語を英語に翻訳します。トークナイザーでソース言語を設定できます。"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from transformers import AutoTokenizer, AutoModelForSeq2SeqLM\n",
    "\n",
    "en_text = \"Do not meddle in the affairs of wizards, for they are subtle and quick to anger.\"\n",
    "fi_text = \"Älä sekaannu velhojen asioihin, sillä ne ovat hienovaraisia ja nopeasti vihaisia.\"\n",
    "\n",
    "tokenizer = AutoTokenizer.from_pretrained(\"facebook/mbart-large-50-many-to-many-mmt\", src_lang=\"fi_FI\")\n",
    "model = AutoModelForSeq2SeqLM.from_pretrained(\"facebook/mbart-large-50-many-to-many-mmt\")"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "テキストをトークン化します。"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "encoded_en = tokenizer(en_text, return_tensors=\"pt\")"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "MBart は、最初に生成されたトークンとしてターゲット言語 ID を強制的にターゲット言語に翻訳します。 英語に翻訳するには、`generate` メソッドで `forced_bos_token_id` を `en` に設定します。"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "\"Don't interfere with the wizard's affairs, because they are subtle, will soon get angry.\""
      ]
     },
     "execution_count": null,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "generated_tokens = model.generate(**encoded_en, forced_bos_token_id=tokenizer.lang_code_to_id(\"en_XX\"))\n",
    "tokenizer.batch_decode(generated_tokens, skip_special_tokens=True)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "`facebook/mbart-large-50-many-to-one-mmt` チェックポイントを使用している場合、最初に生成されたトークンとしてターゲット言語 ID を強制する必要はありません。それ以外の場合、使用方法は同じです。"
   ]
  }
 ],
 "metadata": {},
 "nbformat": 4,
 "nbformat_minor": 4
}
